package it.tukano.swingdeco.text;

import it.tukano.fun.VFunction3;
import it.tukano.swingdeco.controls.JPopupMenuExt;
import it.tukano.text.TextFormat;
import java.awt.Component;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.AbstractButton;
import javax.swing.JTextField;
import javax.swing.text.Document;

public class JTextFieldExt extends JTextField {

    private final JPopupMenuExt menu = new JPopupMenuExt()
            .appendMenuItem("Copia", "copy")
            .appendMenuItem("Incolla", "paste")
            .appendMenuItem("Taglia", "cut")
            .bind(this)
            .onPopupWillBecomeVisible(new Runnable() {

                public void run() {
                    String selectedText = getSelectedText();
                    boolean empty = selectedText == null || selectedText.isEmpty();
                    menu.setButtonState("copy", !empty);
                    menu.setButtonState("cut", !empty);
                    menu.setButtonState("paste", Toolkit.getDefaultToolkit().getSystemClipboard().isDataFlavorAvailable(DataFlavor.stringFlavor));
                }
            })
            .addListener(new VFunction3<Component, Point, AbstractButton>() {

                @Override
                protected void doApply(Component p1, Point p2, AbstractButton p3) {
                    String cmd = p3.getActionCommand();
                    if("copy".equals(cmd)) {
                        copy();
                    } else if("paste".equals(cmd)) {
                        paste();
                    } else if("cut".equals(cmd)) {
                        if(getSelectedText() != null) {
                            selectAll();
                        }
                        cut();
                    }
                }
            });
    
    private static final long serialVersionUID = 0;

    public JTextFieldExt() {
    }

    public JTextFieldExt(int charCount) {
        super(charCount);
    }

    public JTextFieldExt(String string) {
        super(string);
    }
    
    public JTextFieldExt withTip(Object tip) {
        setToolTipText(String.valueOf(tip));
        return this;
    }
    
    public JTextFieldExt setText(Object o) {
        setText(o == null ? "" : o.toString());
        return this;
    }

    public JTextFieldExt withDocument(Document doc) {
        setDocument(doc);
        return this;
    }

    public JTextFieldExt setString(Object value) {
        setText(String.valueOf(value));
        return this;
    }

    /**
     * Return the text in this field or the given predefined value if the text is empty
     * @param string the predefined value
     * @return the text in the field or the predefined value is the field contains no text
     */
    public String getTextOrElse(String string) {
        String text = getText();
        if(text == null || text.trim().isEmpty()) return string;
        return text;
    }

    public JTextFieldExt onActionPerformed(final Runnable task) {
        addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                task.run();
            }
        });
        return this;
    }

    public JTextFieldExt alignCenter() {
        setHorizontalAlignment(JTextField.CENTER);
        return this;
    }

    public boolean isEmpty() {
        return TextFormat.getInstance().isEmpty(getText());
    }

    public boolean containsValidFilePath(boolean mustExist) {
        final String text = getText();
        
        if(text == null || text.isEmpty()) return false;
        
        final File file = new File(text);
        
        if(mustExist && !file.exists()) return false;
        
        return true;
    }

    public File getContentAsDirectory(boolean mustExist) {
        if(getText().isEmpty()) return null;
        File file = new File(getText());
        if(file.isDirectory()) {
            if(mustExist && !file.exists()) {
                return null;
            }
            return file;
        } else {
            return null;
        }
    }

    public JTextFieldExt withName(String string) {
        setName(string);
        return this;
    }

    /** setText("") & return this*/
    public JTextFieldExt clearText() {
        setText("");
        return this;
    }
}
